package org.dtrd.modules.flup.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import org.dtrd.modules.flup.entity.bean.*;
import org.dtrd.modules.flup.entity.po.DtrdEntRdFlupAppointmentRecord;
import org.dtrd.modules.flup.entity.request.FlupAppointmentRecordListRequest;
import org.dtrd.modules.flup.entity.request.FlupAppointmentRecordPageRequest;
import org.dtrd.modules.flup.entity.request.PatientFlup;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 复诊预约记录服务类
 * </p>
 *
 * @author QR
 * @since 2021-12-16
 */
public interface IDtrdEntRdFlupAppointmentRecordService extends IService<DtrdEntRdFlupAppointmentRecord> {

    /**
     * 获取医生的某个日期的预约记录
     *
     * @param request   请求参数
     * @param startDate 时间
     * @return 复诊数据列表
     */
    List<DoctorFlupDaily> getFlupAppointmentRecordList(FlupAppointmentRecordListRequest request, Date startDate);

    IPage<FlupAppointmentRecordListInfo> pageFlupAppointmentRecord(FlupAppointmentRecordPageRequest request);

    FlupAppointmentRecordDetail getFlupAppointmentRecord(Integer dataId);

    boolean saveOrUpdateFlupAppointmentRecord(FlupAppointmentRecordDetail dto);

    boolean removeFlupAppointmentRecord(Integer dataId);

    /**
     * 查询模版是否有正在关联的预约记录
     *
     * @param templateId 项目模版id
     */
    boolean hasTemplateLinkPatient(Integer templateId);

    /**
     * 查询患者本周的复诊记录
     */
    FlupRecord getPatientFlupRecordThisWeek(Integer patientId);

    /**
     * 查询患者最新的预约记录
     */
    FlupRecord getPatientFlupRecordLatest(Integer patientId);

    /**
     * 获取患者本周一开始最新的预约记录
     */
    FlupRecord getPatientFlupRecordStartOfThisWeek(Integer patientId);

    /**
     * 查询指定时间范围内患者的复诊记录
     *
     * @param patientId patientId
     * @param startDate startDate
     * @param endDate   endDate
     * @return 复诊记录列表
     */
    List<FlupAppointmentRecordDetail> listPatientFlupRecord(Integer patientId, Date startDate, Date endDate);

    /**
     * 查询患者是否有正在未完成(进行中)的复诊
     */
    boolean hasPatientUnfinishedFlupRecord(Integer patientId);

    /**
     * 查询患者"本周内"是否有已经完成的复诊记录
     */
    boolean hasPatientFinishedFlupRecordThisWeek(Integer patientId);

    /**
     * 获取患者本周内的门诊预约记录
     */
    List<FlupAppointmentRecordDetail> getPatientFlupThisWeek(Integer patientId);

    /**
     * 获取指定范围内的预约人数
     *
     * @param doctorId  doctorId
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 预约人数
     */
    int countPatientWeekly(Integer doctorId, Date startDate, Date endDate);

    /**
     * 获取指定时间范围内容医生复诊随访排班表
     *
     * @param startDate 开始查询日期
     * @param endDate   结束查询日期
     * @param doctorId
     * @return 医生复诊随访排班表
     */
    List<AppointmentDoctorInfo> getDoctorFlupScheduleByDateRange(Date startDate, Date endDate, Integer doctorId);

    /**
     * 获取可预约医生的列表
     *
     * @param doctorId
     */
    List<AppointmentDoctorInfo> getAppointmentDoctorList(Integer doctorId);

    /**
     * 保存患者的预约门诊记录
     */
    boolean savePatientFlup(PatientFlup patientFlup);

    /**
     * 分页查询患者复诊记录
     */
    IPage<PatientFlupListInfo> pagePatientFlup(Integer patientId,
                                               Date startDate,
                                               Date endDate,
                                               Integer page,
                                               Integer pageSize);

    /**
     * 查询复诊预约结果详情
     */
    FlupRecordDetail getFlupRecordDetail(Integer id);

    /**
     * 查询是否有正在关联模版项目的复诊记录
     *
     * @param id 复诊模版项目id
     */
    boolean hasProjectLinkPatient(Integer id);

    /**
     * 更新复诊状态
     *
     * @param flupId 复诊记录id
     * @param type   根据 type 进行不同状态的修改 type=1 : 状态改成复诊中, type=2 状态改成已复诊
     * @return 操作结果
     */
    boolean updatePatientFlupStatus(Integer flupId, Integer type, String content);
    boolean updatePatientFlupContent(Integer flupId, String content);

    /**
     * 根据 复诊预约记录id 获取复诊流程
     */
    List<FlupFlowItem> getFlupFlow(Integer flupId);

    /**
     * 保存复诊流程内容
     *
     * @param flupFlowItems 复诊流程内容列表
     * @return 保存结果
     */
    @Transactional(rollbackFor = Exception.class)
    boolean saveFlupFlow(List<FlupFlowItem> flupFlowItems, Integer flupId);

    /**
     * 查询医生某日的门诊记录
     *
     * @param doctorId  doctorId
     * @param queryDate 查询日期
     * @return 查询结果
     */
    DoctorFlupDaily getDoctorFlupByDate(Integer doctorId, Date queryDate);

    /**
     * 获取患者的复诊二维码
     *
     * @param type {@link org.dtrd.config.system.Constant.QrCodeType}
     */
    String getPatientFlupQrCode(Integer patientId, Integer type);

    /**
     * 获取完成复诊时的基本信息
     */
    FlupBasicInfo getFlupInfo(Integer flupId);

    /**
     * 获取患者的复诊状态
     */
    Integer getPatientFlupStatus(Integer patientId);

    /**
     * 当前时段是否有患者预约
     */
    Boolean currentTimeHasFlup(Integer doctorId, String flupDate, Integer flupTime);

    /**
     * 删除患者时删除当前已预约状态的复诊记录
     *
     * @param patientIds
     */
    void removeRecordByPatientIds(Set<Integer> patientIds);
}
